//
//  CarModel.m
//  INMOTION
//
//  Created by Kyle on 14-4-24.
//  Copyright (c) 2014年 Inmotion. All rights reserved.
//

#import "CarModel.h"
#import "IMFunction.h"
#import "IMTCarType.h"
#import "IMTUnitHelper.h"
#import "IMTConfig.h"
#import "IMTCANManager.h"

//录制动作采样间隔
const CGFloat kIMTCarSamplingInterval = 0.1f;

//R1车辆宽度
const CGFloat kIMTCarTypeR1BodyWidth = 0.354;

//蓝牙密码支持最低版本
NSString * const kIMTCarTypeR1SupportPasswordVersion = @"3.4.910";
NSString * const kIMTCarTypeR1NSupportOpenRemoteControlVersion = @"3.4.909";

//激活支持版本
NSString * const kIMTCarTypeV3SupportActivationVersion = @"1.7.319";
NSString * const kIMTCarTypeR1R2SupportActivationVersion = @"3.9.326";

//日志上传支持版本
NSString * const kIMTCarTypeV3SupportLogUploadVersion = @"1.7.429";

//L6单次骑行统计数据支持版本
NSString * const kIMTCarTypeL6SupportSingleRideStatisticsVersion = @"1.1.701";

static double kPhaseCurrentFactor = 0.011111;
static double kTorqueFactor = 0.8174;
static double kRotateSpeedFactor = 0.004925;

@interface CarModel ()

@property (nonatomic, strong) NSDictionary *batteryInfo;

@end

@implementation CarModel

- (id)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super initWithCoder:aDecoder]) {
        self.bleName = [aDecoder decodeObjectForKey:@"bleName"];
        self.carName = [aDecoder decodeObjectForKey:@"carName"];
        self.bleAddress = [aDecoder decodeObjectForKey:@"macAdress"];
        self.carId = [aDecoder decodeObjectForKey:@"carId"];
        self.sn = [aDecoder decodeObjectForKey:@"sn"];
        self.carType = [aDecoder decodeObjectForKey:@"carType"];
        self.carTypeName = [aDecoder decodeObjectForKey:@"carTypeName"];
        self.carOwnerType = [aDecoder decodeIntForKey:@"carOwnerType"];
        self.isCarOwner = [aDecoder decodeBoolForKey:@"isCarOwner"];
        self.salesTerritory = [aDecoder decodeObjectForKey:@"salesTerritory"];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.bleName forKey:@"bleName"];
    [aCoder encodeObject:self.carName forKey:@"carName"];
    self.bleAddress = _bleAddress == nil ? @"" : _bleAddress;
    [aCoder encodeObject:self.bleAddress forKey:@"macAdress"];
    [aCoder encodeObject:self.carId forKey:@"carId"];
    [aCoder encodeObject:self.sn forKey:@"sn"];
    NSLog(@"=======  %@  =====",self.carType);
    [aCoder encodeObject:self.carType forKey:@"carType"];
    [aCoder encodeObject:self.carTypeName forKey:@"carTypeName"];
    [aCoder encodeObject:self.salesTerritory forKey:@"salesTerritory"];
    [aCoder encodeInt:self.carOwnerType forKey:@"carOwnerType"];
    [aCoder encodeBool:self.isCarOwner forKey:@"isCarOwner"];
}

- (NSDictionary *)batteryInfo {
    if (!_batteryInfo) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"BatteryInfo" ofType:@"plist"];
        _batteryInfo = [NSDictionary dictionaryWithContentsOfFile:path];
    }
    return _batteryInfo;
}

- (NSMutableArray *)batterySections {
    if (!_batterySections) {
        _batterySections = [[NSMutableArray alloc] init];
    }
    return _batterySections;
}

- (IMTBatteryModel *)batteryModel {
    if (!_batteryModel) {
        _batteryModel = [[IMTBatteryModel alloc] init];
    }
    return _batteryModel;
}

- (instancetype)initWithData:(NSData *)data {
    if (data == nil) {
        return nil;
    }
    self = [super init];
    if (self) {
        IMTCarAdvertisementParams params;
        [data getBytes:&params length:sizeof(params)];
        
        self.model = (params.model >> 8) * 10 + params.model & 0x00FF;
        
        if ((params.content >> 0) & 0x01) {
            NSData *dat = [NSData dataWithBytes:&params.password length:6];
            self.password = [[NSString alloc] initWithData:dat encoding:NSUTF8StringEncoding];
        }
        
        if ((params.content >> 1) & 0x01) {
            
        }
        
        if ((params.content >> 2) & 0x01) {
            self.batteryPercentage = params.batteryPercentage;
        }
    }
    return self;
}

/// 设置固件版本号
- (void)setFirmwareVersion:(NSString *)firmwareVersion {
    _firmwareVersion = firmwareVersion;

    if (IMTCarSeriesR1(self.carType) || IMTCarSeriesR2(self.carType)) {
        self.supportPassword = [IMFunction isTheVersion:firmwareVersion newerThanAnotherVersion:kIMTCarTypeR1SupportPasswordVersion];
        self.supportFirmwareUpdate = self.supportPassword;
        self.supportActivation = [IMFunction isTheVersion:firmwareVersion newerThanAnotherVersion:kIMTCarTypeR1R2SupportActivationVersion];
    } else if (IMTCarSeriesV3(self.carType)){
        self.supportPassword = YES;
        self.supportFirmwareUpdate = YES;
        //除了V3需要根据固件版本判断是否支持激活以外, 其它型号都支持激活
        if ([self.carType isEqualToString:@"020101010100"]) {
            self.supportActivation = [IMFunction isTheVersion:firmwareVersion newerThanAnotherVersion:kIMTCarTypeV3SupportActivationVersion];
        } else {
            self.supportActivation = YES;
        }
    } else if (IMTCarSeriesD1(self.carType) || IMTCarSeriesD2F(self.carType)) {
        self.supportPassword = NO;
        self.supportActivation = NO;
        self.supportFirmwareUpdate = YES;
    } else {
        self.supportPassword = YES;
        self.supportActivation = YES;
        self.supportFirmwareUpdate = YES;
    }
}


// MARK: - 快速数据
- (void)fetchP2Data {
    
    NSLog(@"%@",NSStringFromSelector(_cmd));
    __weak typeof(self)wself = self;
    IMTCANMessage *message = [IMTCANMessageFactory messageWithId:0x0f0b0301];
    [[IMTCANManager sharedInstance] sendMessage:message completion:^(NSError *error, NSData *responseData) {
        if(!error) {
            IMTP2S32Params params;
            [responseData getBytes:&params length:8];
            wself.p2Params = params;
        }
    }];
}
#pragma mark 获取S2数据
- (void)fetchS2Data {
    
    NSLog(@"%@",NSStringFromSelector(_cmd));
    __weak typeof(self)wself = self;
    IMTCANMessage *message = [IMTCANMessageFactory messageWithId:0x0f0b0301];
    [[IMTCANManager sharedInstance] sendMessage:message completion:^(NSError *error, NSData *responseData) {
        if(!error) {
            IMTP2S32Params params;
            [responseData getBytes:&params length:8];
            wself.s2Params = params;
        }
    }];
}

- (void)loadV10FastInfoWithData:(NSData *)data {
    if (data.length < 50) {
        NSLog(@"快速数据长度不够");
        return;
    }
    int offset = 0;
    
    // 速度
    SInt32 speed = 0;
    [data getBytes:&speed range:NSMakeRange(offset, 4)];
    offset += 4;
    self.speed = abs(speed) / 1000.0;
    self.speedControl = MIN(self.currentMaxSpeed, 40 * (self.voltage / 76.7) * (self.voltage / 76.7));
    self.maxRideSpeed = MAX(self.speed, self.maxRideSpeed);
    [self addValue:self.speed toArray:self.speeds limited:false];
   
    // 电流
    SInt32 current = 0;
    [data getBytes:&current range:NSMakeRange(offset, 4)];
    offset += 4;
    self.current = current / 100.0;
    self.maxCurrent = MAX(self.maxCurrent, self.current);
    [self addValue:self.current toArray:self.currents limited:true];
    
    // 电压
    SInt32 voltage = 0;
    [data getBytes:&voltage range:NSMakeRange(offset, 4)];
    offset += 4;
    self.voltage = voltage / 100.0;
    self.maxVoltage = MAX(self.voltage, self.maxVoltage);
    [self addValue:self.voltage toArray:self.voltages limited:true];
    
    // 电量
    self.battery = (self.voltage - 66) / (83 - 66.0);
    self.battery = MAX(self.battery, 0);
    self.battery = MIN(self.battery, 1);
    self.battery = self.battery >= 0.98 ? 1 : self.battery;
    
    // 散热器温度
    SInt8 finTemp = 0;
    [data getBytes:&finTemp range:NSMakeRange(offset, 1)];
    offset += 2; // 忽略右边散热器温度
    self.finTemperature = finTemp;
    self.maxFinTemperature = MAX(self.maxFinTemperature, self.finTemperature);
    [self addValue:self.finTemperature toArray:self.finTemperatures limited:true];
    
    // 电机温度
    SInt8 motorTemp = 0;
    [data getBytes:&motorTemp range:NSMakeRange(offset, 1)];
    offset += 2; // 忽略右边电机温度
    self.motorTemperature = motorTemp;
    self.maxMotorTemperature = MAX(self.maxMotorTemperature, self.motorTemperature);
    [self addValue:self.motorTemperature toArray:self.motorTemperatures limited:true];
    
    // 总里程（如果这里的offset不是4的倍数，旧款车型会死机）
    UInt64 mileage = 0;
    [data getBytes:&mileage range:NSMakeRange(offset, 8)];
    offset += 8;
    self.mileage = (mileage & 0x00000000FFFFFFFF) / 1000.0;
    
    // 开机里程
    self.tripMileage = (mileage >> 32) / 1000.0;
    
    //工作模式 24
    UInt32 mode = 0;
    [data getBytes:&mode range:NSMakeRange(offset, 4)];
    offset += 4;
    self.isTransport = (mode >> 8) & 0x01;  //  测试 -- 是否是运输模式
    self.isLocked = (mode >> 9) & 0x01;
    UInt32 workmodel = mode & 0x0f;

    if (workmodel == 1) {
        self.mode2 = CarModeFree;
    }else if (workmodel == 2){
        self.mode2 = CarModeLoaded;
    }else if (workmodel == 3){
        self.mode2 = CarModeLoaded;
    }else if (workmodel == 4){
        self.mode2 = CarModePowerOff;
    }else {
        self.mode2 = 0;
    }
    // 锁车时工作模式记为锁车状态
    if (self.isLocked) {
        self.mode2 = CarModeLocked;
    }
    // 相电流
    SInt32 phaseCurrent = 0;
    [data getBytes:&phaseCurrent range:NSMakeRange(offset, 4)];
    offset += 4;
    self.phaseCurrent = phaseCurrent * kPhaseCurrentFactor;
    self.maxPhaseCurrent = MAX(self.maxPhaseCurrent, self.phaseCurrent);
    [self addValue:self.phaseCurrent toArray:self.phaseCurrents limited:true];
    
    // 车体温度
    SInt8 bodyTemp = 0;
    [data getBytes:&bodyTemp range:NSMakeRange(offset, 1)];
    offset += 1;
    self.temperature = bodyTemp;
    self.maxTemperature = MAX(self.maxTemperature, self.temperature);
    [self addValue:self.temperature toArray:self.temperatures limited:true];
    
    // 散热风扇状态
    UInt8 fanSpining = 0;
    [data getBytes:&fanSpining range:NSMakeRange(offset, 1)];
    offset += 1;
    self.fanSpinning = fanSpining;
    
    // 总耗能
    UInt32 totalEnergy = 0;
    [data getBytes:&totalEnergy range:NSMakeRange(offset, 4)];
    offset += 4;
    self.totalEnergy = totalEnergy * 2.7778 / 100;
    
    // 平均能耗
    if (self.mileage == 0) {
        self.averageEnergy = 0;
    } else {
        self.averageEnergy = self.totalEnergy / self.mileage;
    }
    
    // 开机耗能
    UInt32 tripEnergy = 0;
    [data getBytes:&tripEnergy range:NSMakeRange(offset, 4)];
    offset += 4;
    self.tripEnergy = tripEnergy * 2.7778 / 1000000;
    
    // 开机能耗
    if (self.tripMileage == 0) {
        self.tripAverageEnergy = 0;
    } else {
        self.tripAverageEnergy = self.tripEnergy / self.tripMileage;
    }
    
    // 开机时长
    UInt32 tripInterval = 0;
    [data getBytes:&tripInterval range:NSMakeRange(offset, 4)];
    offset += 4;
    self.durationString = [IMTUnitHelper timeStringForInterval:tripInterval];
    
    //最高速度
    speed = 0;
    [data getBytes:&speed range:NSMakeRange(offset, 2)];
    offset += 2;
    double tempSpeed = abs(speed) / 100.0;
    self.maxRideSpeed = MAX(tempSpeed, self.maxRideSpeed);
    [self addValue:tempSpeed toArray:self.speeds limited:false];
    
    // 平均速度
    if (tripInterval == 0) {
        self.averageSpeed = 0;
    } else {
        self.averageSpeed = self.tripMileage / (tripInterval / 3600.0);
    }
    
    // 输出功率
    SInt16 outputPower = 0;
    [data getBytes:&outputPower range:NSMakeRange(offset, 2)];
    offset += 2;
    self.outputPower = outputPower;
    self.maxOutputPower = MAX(self.maxOutputPower, self.outputPower);
    [self addValue:self.outputPower toArray:self.outputPowers limited:true];
    
    if (offset < data.length) {
        // 输入功率
        SInt16 inputPower = 0;
        [data getBytes:&inputPower range:NSMakeRange(offset, 2)];
        offset += 2;
        self.power = inputPower;
        self.maxInputPower = MAX(self.maxInputPower, self.power);
        [self addValue:self.power toArray:self.powers limited:false];
        self.totalPower += self.power;
        
        // 平均功率
        self.averagePower = self.totalPower / self.powers.count;
        
        // 效率
        if (self.outputPower == 0) {
            self.efficiency = 0;
        } else {
            self.efficiency = 100 * self.power / self.outputPower;
        }
        self.maxEfficiency = MAX(self.maxEfficiency, self.efficiency);
        [self addValue:self.efficiency toArray:self.efficiencies limited:true];
        
        // 扭矩
        SInt16 torque = 0;
        [data getBytes:&torque range:NSMakeRange(offset, 2)];
        offset += 2;
        self.torque = torque / 100.0;
        self.maxTorque = MAX(self.maxTorque, self.torque);
        [self addValue:self.torque toArray:self.torques limited:true];
        
        //  加速度
        SInt16 acceleration = 0;
        [data getBytes:&acceleration range:NSMakeRange(offset, 2)];
        offset += 2;
        self.acceleratedSpeed = acceleration / 100.0;
        self.maxAcceleratedSpeed = MAX(self.acceleratedSpeed, self.maxAcceleratedSpeed);
        [self addValue:self.acceleratedSpeed toArray:self.acceleratedSpeeds limited:true];
        
        // 能耗 = 功率 / 速度
        if (self.speed == 0) {
            self.energy = 0;
        } else {
            self.energy = self.power / self.speed;
        }
    }else{}
    [self _loadWorkModeFromData:data];
    
    self.maxEnergy = MAX(self.energy, self.maxEnergy);
    [self addValue:self.energy toArray:self.tripEnergies limited:false];
}

- (void)loadFastWorkModelAndSpeedInfoFromCANMessageData:(NSData *)data {
    
    if (IMTCarSeriesV10(self.carType)) {
        if (data.length < 8) {
            NSLog(@"快速数据长度不够");
            return;
        }
        int offset = 0;
       
        // 速度
        SInt32 speed = 0;
        [data getBytes:&speed range:NSMakeRange(offset, 4)];
        offset += 4;
        self.speed = abs(speed) / 1000.0;

        //工作模式
        UInt32 mode = 0;
        [data getBytes:&mode range:NSMakeRange(offset, 4)];
        offset += 4;
        self.isTransport = (mode >> 8) & 0x01;  // 是否是运输模式
        self.isLocked = (mode >> 9) & 0x01;
        UInt32 workmodel = mode & 0x0f;
        if (workmodel == 1) {
            self.mode2 = CarModeFree;
        }else if (workmodel == 2){
            self.mode2 = CarModeLoaded;
        }else if (workmodel == 3){
            self.mode2 = CarModeLoaded;
        }else if (workmodel == 4){
            self.mode2 = CarModePowerOff;
        }else {
            self.mode2 = 0;
        }
        // 锁车时工作模式记为锁车状态
        if (self.isLocked) {
            self.mode2 = CarModeLocked;
        }
    }else {
        int32_t leftSpeed = 0, rightSpeed = 0;
        if (data.length >= 8) {
            [data getBytes:&leftSpeed range:NSMakeRange(0, 4)];
            [data getBytes:&rightSpeed range:NSMakeRange(4, 4)];
            double speed = (abs(leftSpeed) + abs(rightSpeed)) / 2;
            if (IMTCarSeriesR1(self.carType) ||
                IMTCarSeriesR2(self.carType) ||
                IMTCarSeriesL6(self.carType) ||
                IMTCarSeriesL8(self.carType)) {
                if (speed == 0) {
                    speed = 0;
                }
                self.speed = speed / 3812;
            } else {
                if (speed < 0) {
                    speed = -speed;
                }
                self.speed = speed / 1000; // 返回单位是m/h
            }
            NSLog(@"%f -=======%d====🌹定时器获取快速数据结果🌹=======%d=====- %f",speed,leftSpeed,rightSpeed,self.speed);
        }
        self.maxRideSpeed = MAX(self.maxRideSpeed, self.speed);
        [self addValue:self.speed toArray:self.speeds limited:false];
        
        //计算左右行进距离（动作录制）
        if (IMTCarSeriesR1(_carType) || IMTCarSeriesR2(_carType)) {
            float v1 = leftSpeed / (3812.0 * 3.6);
            float v2 = rightSpeed / (3812.0 * 3.6);
            self.s1 = v1 * kIMTCarSamplingInterval;
            self.s2 = v2 * kIMTCarSamplingInterval;
        }

        // 工作模式
        if (data.length >= 12) {
            uint32_t mode = 0;
            [data getBytes:&mode range:NSMakeRange(8, 4)];
            mode = mode & 0xFF;
            if (IMTCarSeriesHC(self.carType)) {
                if (mode >> 4 == 1) {
                    self.mode3 = BeginnerMode;
                } else if (mode >> 4 == 2){
                    self.mode3 = NormalMode;
                } else if (mode >> 4 == 3){
                    self.mode3 = SelfBalancedModel;
                }
            } else {
                if (mode >> 4 == 1) {
                    self.mode1 = CarModeFish;
                } else if (mode >> 4 == 0x0C) {
                    self.mode1 = CarModeShortHandle;
                } else if (mode >> 4 == 0x0F) {
                    self.mode1 = CarModeLocked;
                } else if (mode >> 4 == 0x04) {
                    self.mode1 = CarModeLocked;
                } else {
                    self.mode1 = CarModeFree;
                }
            }
            self.mode2 = mode & 0x0F;
            
            //L6L8利用3-7位判断是否锁车
            if (IMTCarSeriesL6(self.carType) || IMTCarSeriesL8(self.carType)) {
                if (mode >> 4 != 0) {
                    self.mode1 = CarModeLocked;
                } else {
                    self.mode1 = CarModeFree;
                }
            }
        }
    }
}

- (void)loadFastInfoFromCANMessageData:(NSData *)data {
    if (IMTCarSeriesV10(self.carType)) {
        [self loadV10FastInfoWithData:data];
        return;
    }
    [self _loadSpeedFromData:data];
    [self _loadFinTemperatureFromData:data];
    [self _loadCurrentAndVoltageFromData:data];
    [self _loadMotorTemperatureFromData:data];
    [self _loadMileageFromData:data];
    [self _loadWorkModeFromData:data];
    [self _loadTemperatureFromData:data];
    [self _loadErrorCodeFromData:data];
    [self _calculateThisTripFromData:data];
}

// D1散热片温度
- (void)_loadFinTemperatureFromData:(NSData *)data {
    if (IMTCarSeriesD1(self.carType)) {
        int8_t temp = 0;
        if (data.length >= 34) {
            [data getBytes:&temp range:NSMakeRange(32, 1)];
            self.finTemperature = temp;
        }
    }
}

// 速度
- (void)_loadSpeedFromData:(NSData *)data {
    int32_t leftSpeed = 0, rightSpeed = 0;
    if (data.length >= 20) {
        [data getBytes:&leftSpeed range:NSMakeRange(12, 4)];
        [data getBytes:&rightSpeed range:NSMakeRange(16, 4)];
        double speed = (abs(leftSpeed) + abs(rightSpeed)) / 2;
        if (IMTCarSeriesR1(self.carType) ||
            IMTCarSeriesR2(self.carType) ||
            IMTCarSeriesL6(self.carType) ||
            IMTCarSeriesL8(self.carType)) {
            if (speed == 0) {
                speed = 0;
            }
            self.speed = speed / 3812;
        } else {
            if (speed < 0) {
                speed = -speed;
            }
            self.speed = speed / 1000; // 返回单位是m/h
        }
    }
    self.maxRideSpeed = MAX(self.maxRideSpeed, self.speed);
    [self addValue:self.speed toArray:self.speeds limited:false];
    
    //计算左右行进距离（动作录制）
    if (IMTCarSeriesR1(_carType) || IMTCarSeriesR2(_carType)) {
        float v1 = leftSpeed / (3812.0 * 3.6);
        float v2 = rightSpeed / (3812.0 * 3.6);
        self.s1 = v1 * kIMTCarSamplingInterval;
        self.s2 = v2 * kIMTCarSamplingInterval;
    }
}

// 电流
- (void)_loadCurrentAndVoltageFromData:(NSData *)data {
    if (data.length < 72) {
        return;
    }
    
    // 总电流
    int32_t current = 0, voltage = 0;
    [data getBytes:&current range:NSMakeRange(20, 4)];
    self.current = current / 100.0;
    self.maxCurrent = MAX(self.maxCurrent, self.current);
    [self addValue:self.current toArray:self.currents limited:true];
    
    // 相电流
    int32_t leftPhase = 0, rightPhase = 0;
    [data getBytes:&leftPhase range:NSMakeRange(64, 4)];
    [data getBytes:&rightPhase range:NSMakeRange(68, 4)];
    self.phaseCurrent = ((leftPhase + rightPhase) / 2.0) * kPhaseCurrentFactor;
    self.maxPhaseCurrent = MAX(self.maxPhaseCurrent, self.phaseCurrent);
    [self addValue:self.phaseCurrent toArray:self.phaseCurrents limited:true];
    
    // 电压
    [data getBytes:&voltage range:NSMakeRange(24, 4)];
    self.voltage = voltage / 100.0;
    self.maxVoltage = MAX(self.voltage, self.maxVoltage);
    [self addValue:self.voltage toArray:self.voltages limited:true];
    
    // 功率
    self.power = self.current * self.voltage;
    self.maxInputPower = MAX(self.maxInputPower, self.power);
    [self addValue:self.power toArray:self.powers limited:false];
    self.totalPower += self.power;
    self.averagePower = self.totalPower / self.powers.count;
    
    // 扭矩
    self.torque = self.phaseCurrent * kTorqueFactor;
    self.maxTorque = MAX(self.maxTorque, self.torque);
    [self addValue:self.torque toArray:self.torques limited:true];
    
    // 输出功率
    self.outputPower = self.torque * self.speed * 1000 * kRotateSpeedFactor;
    self.maxOutputPower = MAX(self.maxOutputPower, self.outputPower);
    [self addValue:self.outputPower toArray:self.outputPowers limited:true];
    
    // 效率
    if (self.outputPower == 0) {
        self.efficiency = 0;
    } else {
        self.efficiency = 100 * self.power / self.outputPower;
    }
    self.maxEfficiency = MAX(self.maxEfficiency, self.efficiency);
    [self addValue:self.efficiency toArray:self.efficiencies limited:true];
    
    // 电量
    if (IMTCarSeriesD1(self.carType) || IMTCarSeriesD2F(self.carType)) {
        [self _loadBatteryFromData:data];
    } else {
        
        /*
         
         如果能直接从83后一个字节获取到电量值则通过该方式获取，
         如果该通道不存在电量值则通过区间电压方式计算。
         
         */
        // 电量
        if (IMTCarSeriesL8(self.carType)) {
            int32_t value = 0;
            if (data.length >= 84) {
                [data getBytes:&value range:NSMakeRange(83, 1)];
            }
            if (value > 0) { ///  battery = ((buf[83] & 0xfe) >>> 1) * 0.01;
                self.battery = ((value & 0xfe) >> 1) * 0.01; // 车子里只用了七位
                return;
            }
        }

        [self _loadBatteryWithVoltage:voltage];
    }
}

// 电机温度
- (void)_loadMotorTemperatureFromData:(NSData *)data {
    if (data.length < 36) {
        return;
    }
    int8_t leftMotorTem = 0;
    int8_t rightMotorTem = 0;
    [data getBytes:&leftMotorTem range:NSMakeRange(34, 1)];
    [data getBytes:&rightMotorTem range:NSMakeRange(35, 1)];
    if(leftMotorTem >= rightMotorTem) {
        self.motorTemperature = leftMotorTem;
    } else {
        self.motorTemperature = rightMotorTem;
    }
    self.motorTemperature = MAX(leftMotorTem, rightMotorTem);
    self.maxMotorTemperature = MAX(self.maxMotorTemperature, self.motorTemperature);
    [self addValue:self.motorTemperature toArray:self.motorTemperatures limited:true];
}

// 里程
- (void)_loadMileageFromData:(NSData *)data {
    uint64_t mileage = 0;
    if (data.length >= 52) {
        [data getBytes:&mileage range:NSMakeRange(44, 8)];
        NSString *carType = self.carType;
        if (IMTCarSeriesV3(carType) ||
            IMTCarSeriesV5(carType) ||
            IMTCarSeriesV6(carType) ||
            IMTCarSeriesV8(carType) ||
            IMTCarSeriesHC(carType) ||
            IMTCarSeriesB2(carType) ||
            IMTCarSeriesD1(carType) ||
            IMTCarSeriesD2F(carType)) {
            self.mileage = mileage / 1000.0;
        } else if (IMTCarSeriesL6(carType) || (IMTCarSeriesL8(carType))) {
            self.mileage = mileage / 10.0;
        } else if (IMTCarSeriesR1(carType) || IMTCarSeriesR2(carType)) {
            self.mileage = mileage / 57110163.79455429;
        } else if (IMTCarSeriesP(carType)) {
            self.mileage = mileage / 1000.0;
            self.mileage = self.mileage * 1.08; // P1里程加成
        } else {
            self.mileage = 0;
        }
    }
}

// 工作模式
- (void)_loadWorkModeFromData:(NSData *)data {
    uint32_t mode = 0;
    if (data.length >= 64) {
        [data getBytes:&mode range:NSMakeRange(60, 4)];
        mode = mode & 0xFF;
        
        if (IMTCarSeriesV10(self.carType)){
            self.isTransport = (mode >> 8) && 0x01;  //  测试
            return;
        }
        
        if (IMTCarSeriesHC(self.carType)) {
            if (mode >> 4 == 1) {
                self.mode3 = BeginnerMode;
            } else if (mode >> 4 == 2){
                self.mode3 = NormalMode;
            } else if (mode >> 4 == 3){
                self.mode3 = SelfBalancedModel;
            }
        } else {
            if (mode >> 4 == 1) {
                self.mode1 = CarModeFish;
            } else if (mode >> 4 == 0x0C) {
                self.mode1 = CarModeShortHandle;
            } else if (mode >> 4 == 0x0F) {
                self.mode1 = CarModeLocked;
            } else if (mode >> 4 == 0x04) {
                self.mode1 = CarModeLocked;
            } else {
                self.mode1 = CarModeFree;
            }
        }
        self.mode2 = mode & 0x0F;
        
        //L6L8利用3-7位判断是否锁车
        if (IMTCarSeriesL6(self.carType) || IMTCarSeriesL8(self.carType)) {
            if (mode >> 4 != 0) {
                self.mode1 = CarModeLocked;
            } else {
                self.mode1 = CarModeFree;
            }
        }
    }
}

// V8车体温度
- (void)_loadTemperatureFromData:(NSData *)data {
    if (IMTCarSeriesV8(self.carType)) {
        if (data.length >= 101) {
            int8_t temp;
            [data getBytes:&temp range:NSMakeRange(100, 1)];
            self.temperature = temp;
            self.maxTemperature = MAX(self.maxTemperature, self.temperature);
            [self addValue:self.temperature toArray:self.temperatures limited:false];
        }
    }
}

// 计算本次行驶距离
- (void)_calculateThisTripFromData:(NSData *)data {
    if (IMTCarSeriesS2(self.carType)) {
        if (data.length >= 80) {
            uint32_t temp;
            [data getBytes:&temp range:NSMakeRange(76, 4)];
            self.tripMileage = temp *0.001;
        }
        if (self.tripMileage < 0) { //在骑行过程中车辆里的总里程可能会出现丢失，在计算的过程中本次里程可能为负，需清零
            self.tripMileage = 0;
        }
        
        uint32_t temp = 0;
        if (data.length >= 88) {
            [data getBytes:&temp range:NSMakeRange(84, 4)];
            self.durationString = [IMTUnitHelper timeStringForInterval:temp];
        }
        if (temp == 0) {
            self.averageSpeed = 0;
        } else {
            self.averageSpeed = self.tripMileage / (temp / 3600.0);
        }
    }else {
        if (self.previousMileage == 0) {
            self.startDate = [NSDate date];
            self.previousMileage = self.mileage;
        }
        self.tripMileage = self.mileage - self.previousMileage;
        if (self.tripMileage < 0) { //在骑行过程中车辆里的总里程可能会出现丢失，在计算的过程中本次里程可能为负，需清零
            self.tripMileage = 0;
        }
        int interval = [[NSDate date] timeIntervalSinceDate:self.startDate];
        self.durationString = [IMTUnitHelper timeStringForInterval:interval];
        if (interval == 0) {
            self.averageSpeed = 0;
        } else {
            self.averageSpeed = self.tripMileage / (interval / 3600.0);
        }
    }
    
    // 能耗 = 功率 / 速度
    if (self.speed == 0) {
        self.energy = 0;
    } else {
        self.energy = self.power / self.speed;
    }
    
    self.maxEnergy = MAX(self.energy, self.maxEnergy);
    [self addValue:self.energy toArray:self.tripEnergies limited:false];
    
    // 平均能耗
    self.sumOfTripEnergy += self.energy;
    if (self.tripEnergies.count > 0) {
        self.tripAverageEnergy = self.sumOfTripEnergy / self.tripEnergies.count;
    } else {
        self.tripAverageEnergy = 0;
    }
    // 耗能 = 里程 * 平均能耗
    self.tripEnergy = self.tripMileage * self.tripAverageEnergy;
    
    // 能耗为0不计入统计数据
    if (self.energy != 0) {
        self.statistics.totalSamplingCount += 1;
        self.statistics.sumOfTotalEnergy += self.energy;
    }
    if (self.statistics.totalSamplingCount == 0) {
        self.averageEnergy = 0;
    } else {
        self.averageEnergy = self.statistics.sumOfTotalEnergy / self.statistics.totalSamplingCount;
    }
    self.totalEnergy = self.averageEnergy * self.mileage;
    [self saveStatistics];
}

// L6故障检测
- (void)_loadErrorCodeFromData:(NSData *)data {
    if (IMTCarSeriesL6(self.carType) || IMTCarSeriesL8(self.carType)) {
        if (data.length >= 100) {
            u_int32_t errorCode;
            [data getBytes:&errorCode range:NSMakeRange(96, 4)];
        }
    }
}

// 根据电压区间计算电池电量
- (void)_loadBatteryWithVoltage:(int32_t)value {
    float battery = 0;
    NSString *carType = self.carType;
    NSString *typeName = nil;
    
    if (IMTCarSeriesV3(carType) ||
        IMTCarSeriesV5(carType) ||
        IMTCarSeriesV6(carType) ||
        IMTCarSeriesV8V10(carType)) {
        typeName = @"V";
    } else if (IMTCarSeriesL6(carType)) {
        typeName = @"L6";
    } else if (IMTCarSeriesL8(carType)) {
        typeName = @"L8";
    } else if (IMTCarSeriesR1(carType) || IMTCarSeriesR2(carType)) {
        typeName = @"R";
    } else if (IMTCarSeriesP(carType)) {
        typeName = @"P";
    } else if (IMTCarSeriesHC(carType)) {
        typeName = @"C";
    } else if (IMTCarSeriesB2(carType)) {
        typeName = @"B";
    }
    if (typeName == nil) {
        self.battery = 0;
        return;
    }
    NSArray *sections = [self.batteryInfo objectForKey:typeName];
    if (sections.count >= 2) {
        float max = [sections.firstObject floatValue];
        float min = [sections.lastObject floatValue];
        float range = 1.0 / (sections.count - 1);
        if (value >= max) {
            battery = 1;
        } else if (value <= min) {
            battery = 0;
        } else {
            for (int i = 1; i < sections.count; i++) {
                float top = [sections[i-1] floatValue];
                float bottom = [sections[i] floatValue];
                if (value <= top && value > bottom) {
                    battery = ((value - bottom) / (top - bottom)) * range + (sections.count - 1 - i) * range;
                    break;
                }
            }
        }
        self.battery = battery >= 0.96 ? 1 : battery;
    } else {
        self.battery = 0;
    }
}

// D1直接读取电量
- (void)_loadBatteryFromData:(NSData *)data {
    if (data.length >= 102) {
        uint8_t battery = 0;
        [data getBytes:&battery range:NSMakeRange(101, 1)];
        self.battery = battery / 100.0;
    }
}

/// 版本号转化为字符串
- (NSString *)versionStringFromData:(NSData *)data {
    u_int8_t versionInt1 = 0;
    u_int8_t versionInt2 = 0;
    u_int16_t versionInt3 = 0;

    [data getBytes:&versionInt3 range:NSMakeRange(0, 2)];
    [data getBytes:&versionInt2 range:NSMakeRange(2, 1)];
    [data getBytes:&versionInt1 range:NSMakeRange(3, 1)];

    NSString *string = [NSString stringWithFormat:@"%d.%d.%d", versionInt1, versionInt2, versionInt3];

    return string;
}

- (void)loadSimpleFastInfoFromCANMessageData:(NSData *)data {

//    int32_t leftSpeed = 0;
//    int32_t rightSpeed = 0;
//    uint8_t mode = 0;
//
//    if(data.length >= 9) {
//        [data getBytes:&leftSpeed range:NSMakeRange(0, 4)];
//        [data getBytes:&rightSpeed range:NSMakeRange(4, 4)];
//        [data getBytes:&mode range:NSMakeRange(8, 1)];
//    }
//
//    self.speed = (leftSpeed + rightSpeed) / (2 * 3812.0);
//    if (mode >> 4 == 1) {
//        self.mode1 = CarModeFish;
//    } else {
//        self.mode1 = CarModeFree;
//    }
//
//    self.mode2 = mode & 0x0F;
//
//    float v1 = leftSpeed / (3812.0 * 3.6);
//    float v2 = rightSpeed / (3812.0 * 3.6);
//
//    self.s1 = v1 * kIMTCarSamplingInterval;
//    self.s2 = v2 * kIMTCarSamplingInterval;
}

// 旧协议车型、大象协议车型车型代码转化。
- (NSString *)returnCarTypeStringWithNum:(int64_t)carNum {
    NSString *carType = @"010101010100";
    if (carNum >= 0 && carNum < 0x0000000A) { // R1
        carType = @"010101010100";
    }
    if (carNum == 0x00000000) {
        return @"010101010100";
    }
    if (carNum == 0x00000001) {
        return @"010102010100";
    }
    if (carNum == 0x00000002) {
        return @"010103010100";
    }
    if (carNum == 0x00000003) {
        return @"010104010100";
    }
    if (carNum == 0x00000004) {
        return @"010105010100";
    }
    if (carNum == 0x00000005) {
        return @"010106010100";
    }
    if (carNum == 0x00000006) {
        return @"010107010100";
    }
    if (carNum == 0x00000007) {
        return @"010108010100";
    }
    if (carNum == 0x00000008) {
        return @"010109010100";
    }
    if (carNum >= 0x02000000 && carNum < 0x0200000A) { // R2
        carType = @"010201010100";
    }
    if (carNum == 0x02000000) {
        return @"010201010100";
    }
    if (carNum == 0x02000001) {
        return @"010202010100";
    }
    if (carNum == 0x02000004) {
        return @"010203010100";
    }
    if (carNum == 0x12) { // E2
        return @"010301010100";
    }
    if (carNum == 0x020012) { // E2P
        return @"010302010100";
    }
    if (carNum == 0x030012) { // E2 lite
        return @"010303010100";
    }
    if (carNum == 0x010012) { // E3
        return @"010401010100";
    }
    if (carNum == 0x040012) { // E3 lite
        return @"010402010100";
    }
    if (carNum >= 0x01000000 && carNum < 0x0100000A) { // V3
        carType = @"020101010100";
    }
    if (carNum == 0x01000000) {
        return @"020101010100";
    }
    if (carNum == 0x01000001) {
        return @"020102010100";
    }
    if (carNum == 0x01000002) {
        return @"020103010100";
    }
    if (carNum == 0x01000003) {
        return @"020104010100";
    }
    if (carNum == 0x03000000) { // V6
        return @"020201010100";
    }
    if (carNum >= 0x05000000 && carNum < 0x0500000A) { // V5
        carType = @"020301010100";
    }
    if (carNum == 0x05000000) {
        return @"020301010100";
    }
    if (carNum == 0x05000001) {
        return @"020302010100";
    }
    if (carNum == 0x05000002) {
        return @"020303010100";
    }
    if (carNum == 0x05000003) {
        return @"020304010100";
    }
    if (carNum == 0x05000004) {
        return @"020305010100";
    }
    if (carNum == 0x05000005) {
        return @"020306010100";
    }
    if (carNum == 0x05000006) {
        return @"020307010100";
    }
    if (carNum == 0x05000007) {
        return @"020308010100";
    }
    if (carNum == 0x05000008) {
        return @"020309010100";
    }
    if (carNum >= 0x08000000 && carNum < 0x0800000A) { // V8
        carType = @"020401010100";
    }
    if (carNum == 0x08000005) {
        return @"020402010100";
    }
    if (carNum == 0x08000006) {
        return @"020403010100";
    }
    if (carNum == 0x08000007) { // v8s
        return @"020404010100";
    }
    if ((carNum >= 0x0A000000 && carNum < 0x0A00000A) || (carNum >= 0x0E000000 && carNum < 0x0E00000A)) { // V10
        carType = @"020501010100";
    }
    if (carNum == 0x0A000000) {
        return @"020501010100";
    }
    if (carNum == 0x0A000001) {
        return @"020502010100";
    }
    if (carNum == 0x0E000000) {
        return @"020503010100";
    }
    if (carNum == 0x0E000001) {
        return @"020504010100";
    }
    if (carNum == 0x0E000002) {
        return @"020505010100";
    }
    if (carNum == 0x0E000003) {
        return @"020506010100";
    }
    if (carNum == 0x06000000 || carNum == 0x06000001 || carNum == 0x06000003) { // L6
        carType = @"030101010100";
    }
    if (carNum == 0x06000000) {
        return @"030101010100";
    }
    if (carNum == 0x06000001) {
        return @"030201010100";
    }
    if (carNum == 0x06000003) {
        return @"030202010100";
    }
    if (carNum == 0x06000002 || (carNum >= 0x06000004 && carNum < 0x060000ff && carNum != 0x06000006)) { // L8
        carType = @"030401010100";
    }
    if (carNum == 0x06000002) {
        return @"030401010100";
    }
    if (carNum == 0x06000004) {
        return @"030402010100";
    }
    if (carNum == 0x06000008) {
        return @"030403010100";
    }
    if (carNum == 0x06000009) {
        return @"030404010100";
    }
    if (carNum == 0x0600000A) {
        return @"030405010100";
    }
    if (carNum == 0x0600000B) {
        return @"030406010100";
    }
    if (carNum == 0x0600000C) {
        return @"030407010100";
    }
    if (carNum == 0x0600000D) {
        return @"030408010100";
    }
    if (carNum == 0x0600000E) {
        return @"030409010100";
    }
    if (carNum >= 0x07000000 && carNum < 0x070000ff) { // P1
        carType = @"040101010100";
    }
    if (carNum == 0x07000000) {
        return @"040101010100";
    }
    if (carNum == 0x07000001) {
        return @"040102010100";
    }
    if (carNum == 0x07000002) {
        return @"040103010100";
    }
    if (carNum == 0x07000003) {
        return @"040104010100";
    }
    if (carNum >= 0x0F000000 && carNum < 0x0F0000ff) { // P2
        carType = @"040201010100";
    }
    if (carNum == 0x0F000000) {
        return @"040201010100";
    }
    if (carNum == 0x0F000001) {
        return @"040202010100";
    }
    if (carNum == 0x0F000002) {
        return @"040203010100";
    }
    if (carNum == 0x0F000003) {
        return @"040204010100";
    }
    if (carNum == 0x0F000004) {
        return @"040205010100";
    }
    if (carNum >= 0x10000000 && carNum < 0x100000FF) { // P3
        carType = @"040301010100";
    }
    if (carNum == 0x10000000) {
        return @"040301010100";
    }
    if (carNum == 0x10000001) {
        return @"040302010100";
    }
    if (carNum == 0x09000000) { // C1
        return @"050101010100";
    }
    if (carNum == 0x09000002) { // C3
        return @"050201010100";
    }
    if (carNum == 0x0D000000) { // D1
        return @"050301010100";
    }
    if (carNum == 0x0C000001) { // D2F
        return @"050401010100";
    }
    if (carNum == 0x11000000) { // B2
        return @"050501010100";
    }
    return carType;
}

// MARK: - 慢速数据
- (void)loadSlowInfoFromCANMessageData:(NSData *)data {
    u_int64_t serailNumberInt = 0;
    u_int32_t maxSpeedInt = 0;
    u_int32_t handleSensitivity = 0;
    u_int32_t gpsSendGapInt = 0;
    u_int32_t warningToneIsOnInt = 0;
    u_int32_t lightIsOnInt = 0;
    u_int32_t carTypeInt = 0;
    int32_t zeroPointInt = 0;

    uint8_t lightEffectIsOnInt = 0;
    int32_t standBytimeInt = 0;

    NSUInteger length = data.length;
    
    // 型号
    if (length >= 108) {
        [data getBytes:&carTypeInt range:NSMakeRange(104, 4)];
        int carType1 = (carTypeInt & 0xFF000000) >> 24;
        int carType2 = carTypeInt & 0x000000FF;
        
        int oldCarType = carType1 * 10 + carType2;
         if (carType1 == 6 && carType2 == 10) {
            oldCarType = 610;
         }else if (carType1 == 6 && carType2 == 11) {
            oldCarType = 611;
         }else if (carType1 == 6 && carType2 == 12) {
            oldCarType = 612;
         }else if (carType1 == 6 && carType2 == 13) {
             oldCarType = 613;
         }else if (carType1 == 6 && carType2 == 14) {
             oldCarType = 614;
         }
        self.carType = [self returnCarTypeStringWithNum:(int64_t)carTypeInt];
        self.originCarType = [NSString stringWithFormat:@"%d",oldCarType];
    }

    // 序列号sn
    if (length >= 8) {
        [data getBytes:&serailNumberInt range:NSMakeRange(0, 8)];
        self.sn = [IMFunction toHex:serailNumberInt];
    }

    // 硬件版本号
    if(length >= 20) {
       self.hardwareVersion = [self versionStringFromData:[data subdataWithRange:NSMakeRange(16, 4)]];
    }
    
    // 整车软件版本号
    if(length >= 124) {
        self.softwareVersion = [self versionStringFromData:[data subdataWithRange:NSMakeRange(120, 4)]];
    }
    
    // PC软件版本主控版，固件版本 (由于历史原因使用PC软件版本)，理论上固件版本应该是整车软件版本，不过这个加的比较晚，从offset上的就能看出来
    if (length >= 28) {
        self.pcSoftwareVersion = [self versionStringFromData:[data subdataWithRange:NSMakeRange(24, 4)]];
        self.firmwareVersion = self.pcSoftwareVersion;
    }
    
    // MC软件版本驱动版
    if (length >= 36) {
        self.mcSoftwareVersion = [self versionStringFromData:[data subdataWithRange:NSMakeRange(32, 4)]];
    }

    // 最大速度
    if (length >= 64) {
        [data getBytes:&maxSpeedInt range:NSMakeRange(60, 4)];
        if (IMTCarSeriesV3(self.carType) ||
            IMTCarSeriesV5(self.carType) ||
            IMTCarSeriesV6(self.carType) ||
            IMTCarSeriesV8V10(self.carType) ||
            IMTCarSeriesP(self.carType) ||
            IMTCarSeriesHC(self.carType) ||
            IMTCarSeriesB2(self.carType) ||
            IMTCarSeriesD1(self.carType) ||
            IMTCarSeriesD2F(self.carType)) {
            self.currentMaxSpeed = ceilf(maxSpeedInt / 1000.0);
        } else if (IMTCarSeriesL6(self.carType) || IMTCarSeriesL8(self.carType)) {
            self.currentMaxSpeed = maxSpeedInt;
        } else {
            self.currentMaxSpeed = ceilf(maxSpeedInt / 3812.0);
        }
    }

    // 把手灵敏度
    if (length >= 76) {
        [data getBytes:&handleSensitivity range:NSMakeRange(72, 4)];
        self.handleSensitivity = [NSString stringWithFormat:@"%d", handleSensitivity];
    }
    
    //待机时间
    if (IMTCarSeriesV10(self.carType)) {
        if (length >= 132) {
            UInt8 time;
            [data getBytes:&time range:NSMakeRange(131, 1)];
            self.standByTime = time;
        }
    } else {
        if(length >= 56) {
            [data getBytes:&standBytimeInt range:NSMakeRange(52, 4)];
            self.standByTime = standBytimeInt;
        }
    }
    
    if (IMTCarSeriesV10(self.carType)) {
        // V10踏板灵敏度
        if (length >= 125) {
            uint8_t value = 0;
            [data getBytes:&value range:NSMakeRange(124, 1)];
            self.pedalSensitivity = value * 32;
        }
        //驱动模式开关
        if (length >= 133){
            uint8_t value = 0;
            [data getBytes:&value range:NSMakeRange(132, 1)];
            self.driverModeSwitch = value & 0x01;
        }
    }
    // gps发送间隔
    if (length >= 96) {
        [data getBytes:&gpsSendGapInt range:NSMakeRange(92, 4)];
        self.gpsSendGap = [NSString stringWithFormat:@"%d", gpsSendGapInt];
    }
    // 提示音开关
    if (length >= 88) {
        [data getBytes:&warningToneIsOnInt range:NSMakeRange(84, 4)];
        self.warningToneIsOn = warningToneIsOnInt;
    }

    // 灯光开关
    if (length >= 84) {
        [data getBytes:&lightIsOnInt range:NSMakeRange(80, 4)];
        if (IMTCarSeriesD1(self.carType)) {
            
            // 自动灯光开关状态
            self.autoLight = lightIsOnInt;
            
            // 照明灯开关状态
            uint32_t lightOn = 0;
            if (length >= 100) {
                [data getBytes:&lightOn range:NSMakeRange(96, 4)];
                self.lightIsOn = lightOn;
            }
            
        } else {
            self.lightIsOn = lightIsOnInt;
        }
    }

    // 前后零点
    if (length >= 60) {
        [data getBytes:&zeroPointInt range:NSMakeRange(56, 4)];
        self.zeroPoint = [NSString stringWithFormat:@"%.1f", zeroPointInt / 65536.0];
        if (IMTCarSeriesP(self.carType)) {
            self.cruiseControl = zeroPointInt;
        }
    }

    // 灯效开关
    if (length >= 131) {
        [data getBytes:&lightEffectIsOnInt range:NSMakeRange(130, 1)];
        self.lightEffectIsOn = lightEffectIsOnInt;
		self.atmosphereLampIsOn = lightEffectIsOnInt;
    }

    // 电量分段信息
    if ((IMTCarSeriesL6(self.carType) && self.batterySections.count == 0) || (IMTCarSeriesL8(self.carType) && self.batterySections.count == 0)) {
        if (length >= 120) {
            int offset = 108;
            for (int i = 0; i < 6; i++) {
                u_int16_t section = 0;
                [data getBytes:&section range:NSMakeRange(offset, 2)];
                offset += 2;
                [self.batterySections addObject:@(section)];
            }
        }
    }
    
    uint8_t childLock = 0;
    // p2新功能  by lgh
    if (IMTCarSeriesP(self.carType)) {
        // 儿童锁
        if (length >= 130) {
            [data getBytes:&childLock range:NSMakeRange(129, 1)];
            self.isChildLock = (childLock & 0x2) >> 1;
            /// P2新加超速报警功能 -- 版本要求1.2.10
            self.isOverSpeedAlarlm = (childLock & 0x8) >> 3;
        }
    }
    
    self.versionData = [NSMutableArray arrayWithCapacity:1];
    NSArray *devices = [IMFunction returnCarDevices:self.carType].allValues;
    
    NSDictionary *dict = @{@"device":devices.firstObject == nil ? @"" : devices.firstObject,@"appVersion":self.firmwareVersion.length != 0 ? self.firmwareVersion : @"",@"hwVersion":self.hardwareVersion.length != 0 ? self.hardwareVersion : @""};
    if (![self.versionData containsObject:dict]) {
        [self.versionData addObject:dict];
    }
    if (self.mcSoftwareVersion && !IMTCarSeriesP(self.carType)) {
        NSDictionary *dict = @{@"device":devices.lastObject == nil ? @"" : devices.lastObject,@"appVersion":self.mcSoftwareVersion.length != 0 ? self.mcSoftwareVersion : @"",@"hwVersion":self.hardwareVersion.length != 0 ? self.hardwareVersion : @""};
        if (![self.versionData containsObject:dict]) {
            [self.versionData addObject:dict];
        }
    }
}

//加载音量
- (void)loadVolumeFromCANMessage:(NSData *)data {
    u_int32_t volume;
    [data getBytes:&volume range:NSMakeRange(0, 4)];
    self.volume = [NSString stringWithFormat:@"%d", volume];
}

//加载滑行时间
- (void)loadSlidingTimeFromCANMessage:(NSData *)data {
    u_int32_t slidingTime;
    [data getBytes:&slidingTime range:NSMakeRange(0, 4)];
    self.slidingTime = [NSString stringWithFormat:@"%d",slidingTime];
}

- (void)loadDefaultLanguageFromCANMessage:(NSData *)data {
    u_int32_t language;
    [data getBytes:&language range:NSMakeRange(0, 4)];
    self.language = [NSString stringWithFormat:@"%d", language];
}

- (void)loadL8MCInfoFromData:(NSData *)data {
    if (data.length > 3) {
        uint8_t cruiseIsOn = 0, isPassionMode = 0;
        [data getBytes:&isPassionMode range:NSMakeRange(1, 1)];
        [data getBytes:&cruiseIsOn range:NSMakeRange(2, 1)];
        self.cruiseControl = cruiseIsOn;
        self.isPassionMode = isPassionMode;
    }
}

// MARK: - 缓存
- (void)saveStatistics {

}

+ (void)removeCurrentCar {

}

- (void)saveCurrentCar {

    self.bleAddress = self.bleAddress.length == 0 ? @"00:00:00:00:00:00" : self.bleAddress;
    NSDictionary *dic = @{
                          @"btMac" : self.bleAddress,
                          @"carType" : self.carType,
                          @"bleName" : self.bleName,
                          @"sn" : self.sn ? self.sn : @"",
                          @"appVersion" : self.firmwareVersion? self.firmwareVersion : @""
                          };
    NSLog(@"🌹🌹🌹本地保存当前的设备 ====== %@", dic);
    
    [[NSUserDefaults standardUserDefaults] setObject:dic forKey:@"CurrentCar"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)loadCurrentCar {
    NSDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:@"CurrentCar"];
    if (![dic[@"carType"] isKindOfClass:[NSString class]]) {
        [self clearData];
        return;
    }
    NSLog(@"🌹🌹🌹获取本地当前的设备 ====== %@", dic);
    self.bleAddress = [dic objectForKey:@"btMac"];
    self.sn = [dic objectForKey:@"sn"];
    self.carType = [dic objectForKey:@"carType"];
    self.bleName = [dic objectForKey:@"btName"];
    self.firmwareVersion = dic[@"appVersion"];
}

- (void)clearData {
    [self.currents removeAllObjects];
    self.current = 0;
    self.maxCurrent = 0;

    [self.phaseCurrents removeAllObjects];
    self.phaseCurrent = 0;
    self.maxPhaseCurrent = 0;
    
    [self.voltages removeAllObjects];
    self.voltage = 0;
    self.maxVoltage = 0;
    
    [self.powers removeAllObjects];
    self.power = 0;
    self.maxInputPower = 0;
    self.averagePower = 0;
    self.totalPower = 0;
    
    [self.speeds removeAllObjects];
    self.averageSpeed = 0;
    self.maxRideSpeed = 0;
    self.speed = 0;
    
    [self.torques removeAllObjects];
    self.maxTorque = 0;
    self.torque = 0;
    
    [self.outputPowers removeAllObjects];
    self.maxOutputPower = 0;
    self.outputPower = 0;
    
    [self.efficiencies removeAllObjects];
    self.efficiency = 0;
    self.maxEfficiency = 0;
    
    [self.acceleratedSpeeds removeAllObjects];
    self.acceleratedSpeed = 0;
    self.maxAcceleratedSpeed = 0;
    
    [self.temperatures removeAllObjects];
    self.maxTemperature = 0;
    self.temperature = 0;
    
    [self.motorTemperatures removeAllObjects];
    self.maxMotorTemperature = 0;
    self.motorTemperature = 0;
    
    [self.finTemperatures removeAllObjects];
    self.maxFinTemperature = 0;
    self.finTemperatures = 0;
    
    [self.tripEnergies removeAllObjects];
    self.maxEnergy = 0;
    self.energy = 0;
    self.tripEnergy = 0;
    self.tripMileage = 0;
    self.tripAverageEnergy = 0;
    self.sumOfTripEnergy = 0;
    self.totalEnergy = 0;
    self.averageEnergy = 0;
    
    // 用于统计本次里程
    self.previousMileage = 0;
    self.startDate = nil;
    
    [self saveStatistics];
    _statistics = nil;
}

- (void)loadCarInfoWithDictionary:(NSDictionary *)carInfo {
    self.maxSpeed = [carInfo[@"maxSpeed"] floatValue];
    self.safeSpeed = [carInfo[@"safeSpeed"] floatValue];
    self.leftMiles = [carInfo[@"rangeMileage"] floatValue];
    self.maxPower = [carInfo[@"maxPower"] doubleValue];
    self.standPower = [carInfo[@"ratedPower"] doubleValue];
    self.maxRecoveryPower = [carInfo[@"maxRecoveryPower"] doubleValue];
    self.isCarOwner = [carInfo[@"isCarOwner"] boolValue];
    self.carOwnerType = [carInfo[@"carOwnerType"] intValue];
    self.carId = carInfo[@"carId"];
    self.carTypeName = carInfo[@"carTypeName"];
    self.carType = carInfo[@"carType"];
    self.salesTerritory = carInfo[@"salesTerritory"];
}

#pragma mark - 加载车类型 从本地读取
- (void)loadCarTypeInfo {

}
#pragma mark - =======R0========= complex
- (void)loadR0ComplexDataFromData:(NSData *)data withSId:(u_int8_t)ID {
    if (ID == 45) {
        if (data.length < 64) {
            return;
        }
        // 工作模式
        uint16_t workMode ;
        [data getBytes:&workMode range:NSMakeRange(0, 2)];
        switch (workMode) {  // 0待机，1助力，2骑行，3锁车，4蓝牙遥控
            case 0:
                self.mode2 = CarModeFree;
                break;
            case 1:
                self.mode2 = CarModeAssistant;
                break;
            case 2:
                self.mode2 = CarModeLoaded;
                break;
            case 3:
                self.mode2 = CarModeLocked;
                break;
            case 4:
                self.mode2 = CarModeAutoWalk;
                break;
            default:
                break;
        }
        
        // 电量
        uint16_t battery ;
        [data getBytes:&battery range:NSMakeRange(6, 2)];
        self.battery = battery / 100.0;
        
        // 速度
        uint16_t speed ;
        [data getBytes:&speed range:NSMakeRange(14, 2)];
        self.speed = speed / 1000.0;
        if (self.speed > 30) {
            self.speed = (65.536 - self.speed);
        }
        if (self.speed < 0.01) {
            self.speed = 0.00;
        }
        self.maxRideSpeed = MAX(self.speed, self.maxRideSpeed);
        
        // 总里程
         uint32_t mileage ;
         [data getBytes:&mileage range:NSMakeRange(20, 4)];
         double ridemileage = mileage / 1000.0;
        uint32_t boostDistance ;
        [data getBytes:&boostDistance range:NSMakeRange(24, 4)];
        double boostmile = boostDistance / 1000.0;
        self.mileage = ridemileage + boostmile;
        
        // 本次里程
         uint16_t thismileage ;
         [data getBytes:&thismileage range:NSMakeRange(32, 2)];
         double thisridemileage = thismileage / 100.0;
        uint16_t thisboostDistance ;
        [data getBytes:&thisboostDistance range:NSMakeRange(34, 2)];
        double thisboostmile = thisboostDistance / 100.0;
        self.tripMileage = thisridemileage + thisboostmile;
        
        // 本次运行时间
         uint16_t thistime ;
         [data getBytes:&thistime range:NSMakeRange(54, 2)];
        self.durationString = [IMTUnitHelper timeStringForInterval:thistime];
        uint16_t ridetime ;
        [data getBytes:&ridetime range:NSMakeRange(56, 2)];
        double thisridetime = ridetime;
        uint16_t boosttime ;
        [data getBytes:&boosttime range:NSMakeRange(58, 2)];
        double thisboosttime = boosttime ;
       self.averageSpeed = (thisridetime + thisboosttime) <= 0 ? 0 :self.mileage / (thisridetime + thisboosttime);
        if (self.averageSpeed > self.maxRideSpeed) {
            self.averageSpeed = self.maxRideSpeed;
        }

        // 温度
        uint16_t temp ;
        [data getBytes:&temp range:NSMakeRange(62, 2)];
        self.temperature = temp / 10.0;
        self.maxTemperature = MAX(self.maxTemperature, self.temperature);
    }
}

#pragma mark - =======R0=========
- (void)loadR0DataFromData:(NSData *)data withSId:(u_int8_t)ID{
    if (!self.versionData) {
        self.versionData = [NSMutableArray arrayWithCapacity:1];
    }
    if (ID == 1) {
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        
        str = [self getSoftVersionWithStr:str];
        self.softwareVersion = str;
        NSDictionary *dict = @{@"appVersion":str,@"device":@(0x0a)};
        if (![self.versionData containsObject:dict]) {
            [self.versionData addObject:dict];
        }
    }else if (ID == 22){
        NSMutableData *mData = [[NSMutableData alloc] initWithData:data];
        NSData *testData = [mData subdataWithRange:NSMakeRange(0, 8)];
        NSString *str = [[self transformCharateristicValueFromData:testData] uppercaseString];
        self.sn = str;
    }else if (ID == 31){ // 车系车型
        uint32_t carType ;
        [data getBytes:&carType range:NSMakeRange(0, 4)];

        uint16_t carType1 ;
        [data getBytes:&carType1 range:NSMakeRange(0, 2)];
        uint16_t carType2 ;
        [data getBytes:&carType2 range:NSMakeRange(0, 2)];

        if ([self.carName hasPrefix:@"E2P"] && carType == 0) {
            carType = 0x0212;
        }
        self.carType = [self returnCarTypeStringWithNum:carType];
        int oldCarType = carType1 * 10 + carType2;
        self.originCarType = [NSString stringWithFormat:@"%d",oldCarType];
    }else if (ID == 159){ // 转向灵敏度
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [NSString stringWithFormat:@"%.0f",(CGFloat)strtoul([str UTF8String],0,16)];
        self.handleSensitivity = str;
    }else if (ID == 160){ // 骑行灵敏度/踏板灵敏度
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [NSString stringWithFormat:@"%.0f",(CGFloat)strtoul([str UTF8String],0,16)];
        self.pedalSensitivity = [str integerValue];
    }else if (ID == 161){ // 助力模式平衡点
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [NSString stringWithFormat:@"%ld",strtoul([str UTF8String],0,16)];
        NSInteger temp = [str integerValue];
        if (temp > 200) {
            temp = -(65536 - temp);
        }
        self.assistModeValue = temp / 10;
    }else if (ID == 48){ // 电池剩余百分比
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        self.battery = [str doubleValue] / 100.0;
    }else if (ID == 43){ // 当前车速模式:系统状态标志。Bit0-限速标志，bit1锁车标志，初学者/普通 r0MaxSpeedModel
        int16_t result;
        [data getBytes:&result range:NSMakeRange(0, 1)];
        self.r0MaxSpeedModel = result & 0x01;
    }else if (ID == 52){ // 当前车速 单位 m/h
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        
        SInt32 speed = [str intValue];

        self.speed = abs(speed) / 1000.0;
        if (self.speed > 30) {
            self.speed = (65.536 - self.speed);
        }
        if (self.speed < 0.01) {
            self.speed = 0.00;
        }
        self.maxRideSpeed = MAX(self.speed, self.maxRideSpeed);
        [self addValue:self.speed toArray:self.speeds limited:false];
        
        // 能耗 = 功率 / 速度
        if (self.speed == 0) {
            self.energy = 0;
        } else {
            self.energy = self.power / self.speed;
        }
        
        self.maxEnergy = MAX(self.energy, self.maxEnergy);
        [self addValue:self.energy toArray:self.tripEnergies limited:false];
        
        // 平均能耗
        self.sumOfTripEnergy += self.energy;
        if (self.tripEnergies.count > 0) {
            self.tripAverageEnergy = self.sumOfTripEnergy / self.tripEnergies.count;
        } else {
            self.tripAverageEnergy = 0;
        }
        // 耗能 = 里程 * 平均能耗
        self.tripEnergy = self.tripMileage * self.tripAverageEnergy;
        
        // 能耗为0不计入统计数据
        if (self.energy != 0) {
            self.statistics.totalSamplingCount += 1;
            self.statistics.sumOfTotalEnergy += self.energy;
        }
        if (self.statistics.totalSamplingCount == 0) {
            self.averageEnergy = 0;
        } else {
            self.averageEnergy = self.statistics.sumOfTotalEnergy / self.statistics.totalSamplingCount;
        }
        self.totalEnergy = self.averageEnergy * self.mileage;
        [self saveStatistics];
        
    }else if (ID == 210){ // 开关控制 -- 灯光  Mark：--- 209 改为210
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        self.r0LightState = [str integerValue];
        
    }else if (ID == 209){ // 后退超速报警开关 0关，1开
        uint8_t backAlarm = 0;
        [data getBytes:&backAlarm range:NSMakeRange(0, 1)];
        /// r0 后退超速报警
        self.r0BackOutSpeedState = backAlarm;
    }else if (ID == 120){ // 打开关闭遥控模式
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        if ([str integerValue] == 1) {
            self.mode2 = CarModeAutoWalk;
        }
    }else if (ID == 114){
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        self.currentMaxSpeed = [str floatValue]/1000;
        
    }else if (ID == 102) { // 固件的软件版本号
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self getSoftVersionWithStr:str];
        NSDictionary *dict = @{@"appVersion":str,@"device":@(0x0b)};
        if (![self.versionData containsObject:dict]) {
            [self.versionData addObject:dict];
        }
        if (self.softwareVersion) {
            self.firmwareVersion = [NSString stringWithFormat:@"%@(MC) %@(BT)",self.softwareVersion,str];
        }else{
            self.firmwareVersion = [NSString stringWithFormat:@"%@",str];
        }
    }else if (ID == 45){ // 工作模式
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];        
        str = [self hexCovertToStr:str];
        NSInteger statusNum = [str integerValue];
        switch (statusNum) {  // 0待机，1助力，2骑行，3锁车，4蓝牙遥控
            case 0:
                self.mode2 = CarModeFree;
                break;
            case 1:
                self.mode2 = CarModeAssistant;
                break;
            case 2:
                self.mode2 = CarModeLoaded;
                break;
            case 3:
                self.mode2 = CarModeLocked;
                break;
            case 4:
                self.mode2 = CarModeAutoWalk;
                break;
            default:
                break;
        }
        
    }else if (ID == 72){ // 本次运行时间
        UInt32 tripInterval = 0;
        
        NSMutableData *mData = [[NSMutableData alloc] initWithData:data];
        NSData *allTimeData = [mData subdataWithRange:NSMakeRange(0, 2)];
        NSData *rideTimeData = [mData subdataWithRange:NSMakeRange(2, 2)];
        NSData *boostTimeData = [mData subdataWithRange:NSMakeRange(4, 2)];
        
        allTimeData = [self dataTransfromBigOrSmall:allTimeData];
        NSString *str = [self transformCharateristicValueFromData:allTimeData];
        str = [self hexCovertToStr:str];
        tripInterval = (UInt32)[str integerValue];
        
        self.durationString = [IMTUnitHelper timeStringForInterval:tripInterval];
        
        UInt64 rideTime = 0;
        rideTimeData = [self dataTransfromBigOrSmall:rideTimeData];
        NSString *rideTimeDataStr = [self transformCharateristicValueFromData:rideTimeData];
        rideTimeDataStr = [self hexCovertToStr:rideTimeDataStr];
        rideTime = (UInt64)[str integerValue];
        
        boostTimeData = [self dataTransfromBigOrSmall:boostTimeData];
        NSString *boostTimeDataStr = [self transformCharateristicValueFromData:boostTimeData];
        boostTimeDataStr = [self hexCovertToStr:boostTimeDataStr];
        rideTime = (UInt64)[boostTimeDataStr integerValue] + rideTime;
        
        self.averageSpeed = (double)self.mileage / rideTime;
    }else if (ID == 55){ // 总骑行里程
        double mileage = 0;
        NSData *testData = [NSData dataWithBytes:data.bytes length:4];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        mileage = [str doubleValue] / 1000;
        double boostDistance = 0;
        NSMutableData *mData = [[NSMutableData alloc] initWithData:data];
        NSData *boostDistanceData = [mData subdataWithRange:NSMakeRange(4, 4)];
        boostDistanceData = [self dataTransfromBigOrSmall:boostDistanceData];
        NSString *boostDistanceDataStr = [self transformCharateristicValueFromData:boostDistanceData];
        boostDistanceDataStr = [self hexCovertToStr:boostDistanceDataStr];
        boostDistance = [boostDistanceDataStr doubleValue] / 1000;
       
        self.mileage = mileage + boostDistance;
    }else if (ID == 61){ // 本次骑行里程
        double mileage = 0;
        NSData *testData = [NSData dataWithBytes:data.bytes length:4];
        
        NSMutableData *mData = [[NSMutableData alloc] initWithData:testData];
        NSData *rideDistanceData = [mData subdataWithRange:NSMakeRange(0, 2)];
        NSData *boostDistanceData = [mData subdataWithRange:NSMakeRange(2, 2)];
        
        rideDistanceData = [self dataTransfromBigOrSmall:rideDistanceData];
        NSString *rideStr = [self transformCharateristicValueFromData:rideDistanceData];
        rideStr = [self hexCovertToStr:rideStr];
        mileage = (double)[rideStr doubleValue] / 100;
        
        boostDistanceData = [self dataTransfromBigOrSmall:boostDistanceData];
        NSString *str = [self transformCharateristicValueFromData:boostDistanceData];
        str = [self hexCovertToStr:str];
        mileage = (double)[str doubleValue] / 100 + mileage;
        self.tripMileage = mileage;
    }else if (ID == 76){ // 姿态温度
        UInt16 temp = 0;
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        temp = (UInt16)[str integerValue] / 10;
        self.temperature = temp;
        self.maxTemperature = MAX(self.maxTemperature, self.temperature);
        [self addValue:self.temperature toArray:self.temperatures limited:true];
    }else if (ID == 85){ // 电池电压
        UInt64 temp = 0;
        NSData *testData = [NSData dataWithBytes:data.bytes length:2];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        temp = [str doubleValue] / 100;
        self.voltage = temp;
    }else if (ID == 186){ // 动态限速
        UInt64 temp = 0;
        NSMutableData *mData = [[NSMutableData alloc] initWithData:data];
        NSData *testData = [mData subdataWithRange:NSMakeRange(0, 2)];
        testData = [self dataTransfromBigOrSmall:testData];
        NSString *str = [self transformCharateristicValueFromData:testData];
        str = [self hexCovertToStr:str];
        temp = (UInt64)[str integerValue] / 10;
        self.speedControl = temp;
    }
}

// 获取固件升级状态
- (void)getCarUpdateStateWithSuccessBlock:(void (^)(NSError *error, NSDictionary *result))success failBlock:(IMNewCarModelSettingFailBlock)fail {

}

- (NSString *)transformCharateristicValueFromData:(NSData *)dataValue{
    if (!dataValue || [dataValue length] == 0) {
        return @"";
    }
    NSMutableString *destStr = [[NSMutableString alloc] initWithCapacity:[dataValue length]];
    
    [dataValue enumerateByteRangesUsingBlock:^(const void * _Nonnull bytes, NSRange byteRange, BOOL * _Nonnull stop) {
        unsigned char *dataBytes = (unsigned char *)bytes;
        for (int i = 0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x",(dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [destStr appendString:hexStr];
            }else{
                [destStr appendFormat:@"0%@",hexStr];
            }
        }
    }];
    return destStr;
}

#pragma mark - 高低位转换
- (NSString *)covertToStr:(NSString *)str{
    NSInteger num = str.length / 2;
    NSString *highStr = [str substringToIndex:num];
    NSString *lowStr = [str substringFromIndex:num];
    
    NSString *resultStr = [NSString stringWithFormat:@"%@%@",lowStr,highStr];
    resultStr = [NSString stringWithFormat:@"%ld",(long)[resultStr integerValue]];
    return resultStr;
}

- (NSString *)hexCovertToStr:(NSString *)hexStr{
    NSString *str = [NSString stringWithFormat:@"%lu",strtoul([hexStr UTF8String], 0, 16)];
    return str;
}

- (NSData *)dataTransfromBigOrSmall:(NSData *)data{
    
    NSString *tmpStr = [self dataChangeToString:data];
    NSMutableArray *tmpArra = [NSMutableArray array];
    for (int i = 0 ;i<data.length*2 ;i+=2) {
        NSString *str = [tmpStr substringWithRange:NSMakeRange(i, 2)];
        [tmpArra addObject:str];
    }
    
    NSArray *lastArray = [[tmpArra reverseObjectEnumerator] allObjects];
    
    NSMutableString *lastStr = [NSMutableString string];
    
    for (NSString *str in lastArray) {
        [lastStr appendString:str];
    }
    
    NSData *lastData = [self HexStringToData:lastStr];
    
    return lastData;
}

// 适配iOS13的data转字符串
- (NSString*)dataChangeToString:(NSData*)data{
    if (@available(iOS 13.0, *)) {
        NSMutableString *mutableString = [NSMutableString string];
        const char *bytes = data.bytes;
        NSInteger count = data.length;
        for (int i = 0; i < count; i++) {
            [mutableString appendFormat:@"%0.2hhx", bytes[i]];
        }
        return (NSString *)mutableString;
    } else {
        NSString * string = [NSString stringWithFormat:@"%@",data];
        string = [string stringByReplacingOccurrencesOfString:@"<" withString:@""];
        string = [string stringByReplacingOccurrencesOfString:@">" withString:@""];
        string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
        return string;
    }
}

- (NSMutableData*)HexStringToData:(NSString*)str{
    NSString *command = str;
    command = [command stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSMutableData *commandToSend= [[NSMutableData alloc] init];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i=0; i < [command length]/2; i++) {
        byte_chars[0] = [command characterAtIndex:i*2];
        byte_chars[1] = [command characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [commandToSend appendBytes:&whole_byte length:1];
    }
    return commandToSend;
}

//十六进制转十进制
- (NSString *)hexToStr:(NSString *)hexStr{
    NSString *str = [NSString stringWithFormat:@"%lu",strtoul([hexStr UTF8String], 0, 16)];
    return str;
}

/*
 * 0701 高低位转换为 0107 版本号 1.0.7
 */
- (NSString *)getSoftVersionWithStr:(NSString *)str{
    NSString *resultStr = [str substringWithRange:NSMakeRange(0, 1)];
    if ([resultStr isEqualToString:@"0"]) {
        resultStr = @"";
    }
    for (NSInteger i = 1; i < str.length; i++) {
        NSString *subStr = [NSString stringWithFormat:@"%ld",(long)[[self hexToStr:[str substringWithRange:NSMakeRange(i, 1)]] integerValue]];

        if ([resultStr isEqualToString:@""]) {
            resultStr = [NSString stringWithFormat:@"%@",subStr];
        }else{
            resultStr = [NSString stringWithFormat:@"%@.%@",resultStr,subStr];
        }
    }
    return resultStr;
}

#pragma mark - Statistics

- (void)addValue:(double)value toArray:(NSMutableArray *)array limited:(BOOL)limited {
    if (limited && array.count >= 100) {
        [array removeObjectAtIndex:0];
    }
    [array addObject:@(value)];
}

- (NSMutableArray *)currents {
    if (!_currents) {
        _currents = @[].mutableCopy;
    }
    return _currents;
}

- (NSMutableArray *)phaseCurrents {
    if (!_phaseCurrents) {
        _phaseCurrents = @[].mutableCopy;
    }
    return _phaseCurrents;
}

- (NSMutableArray *)voltages {
    if (!_voltages) {
        _voltages = @[].mutableCopy;
    }
    return _voltages;
}

- (NSMutableArray *)powers {
    if (!_powers) {
        _powers = @[].mutableCopy;
    }
    return _powers;
}

- (NSMutableArray *)speeds {
    if (!_speeds) {
        _speeds = @[].mutableCopy;
    }
    return _speeds;
}

- (NSMutableArray *)torques {
    if (!_torques) {
        _torques = @[].mutableCopy;
    }
    return _torques;
}

- (NSMutableArray *)outputPowers {
    if (!_outputPowers) {
        _outputPowers = @[].mutableCopy;
    }
    return _outputPowers;
}

- (NSMutableArray *)efficiencies {
    if (!_efficiencies) {
        _efficiencies = @[].mutableCopy;
    }
    return _efficiencies;
}

- (NSMutableArray *)acceleratedSpeeds {
    if (!_acceleratedSpeeds) {
        _acceleratedSpeeds = @[].mutableCopy;
    }
    return _acceleratedSpeeds;
}

- (NSMutableArray *)temperatures {
    if (!_temperatures) {
        _temperatures = @[].mutableCopy;
    }
    return _temperatures;
}

- (NSMutableArray *)motorTemperatures {
    if (!_motorTemperatures) {
        _motorTemperatures = @[].mutableCopy;
    }
    return _motorTemperatures;
}

- (NSMutableArray *)finTemperatures {
    if (!_finTemperatures) {
        _finTemperatures = @[].mutableCopy;
    }
    return _finTemperatures;
}

- (NSMutableArray *)tripEnergies {
    if (!_tripEnergies) {
        _tripEnergies = @[].mutableCopy;
    }
    return _tripEnergies;
}

@end
